﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace _15.async
{
    class Program
    {
        //Action/Func # BeiginInvoke/EndInvoke
        static void Main(string[] args)
        {
            //{
            //    //1.
            //    Action a = Incr;
            //    Action b = Print;
            //    Action.Combine(a, b).DynamicInvoke(); //Action.Combine 是顺序调用，本身也不是多线程

            //    Console.WriteLine("------------------------start async");

            //    //2.
            //    AsyncCallback cb = (_r) => //定义一个回调，注意回调的参数
            //    { //这里的r很有意思
            //    Console.WriteLine("r.AsyncState: {0}", _r.AsyncState);
            //        Console.WriteLine("r.IsCompleted: {0}", _r.IsCompleted);
            //    };
            //    //异步执行a
            //    var r = a.BeginInvoke(cb, null);
            //}


            //{//获取异步执行的结果1
            //    Func<int, int> func = AddAndGet;
            //    var res = func.BeginInvoke(88, r => //如果委托的方法需要参数，那在最前面加入
            //    {
            //        Console.WriteLine("r.AsyncState: {0}", r.AsyncState); //AsyncState 是传入的参数 "123"！
            //        Console.WriteLine("r.IsCompleted: {0}", r.IsCompleted);
            //    }, "123"); //最后这个是用来玩的？


            //    if (res.AsyncWaitHandle.WaitOne()) //阻塞、等待完成 - 可以设置等待时间！ 又成了顺序执行了
            //    {
            //        Console.WriteLine("result is {0}", func.EndInvoke(res)); //func.EndInvoke(res) 可以获取返回结果！
            //    }
            //}

            {//获取异步执行的结果2 - 改进
                Func<int, int> func = AddAndGet;
                var res = func.BeginInvoke(88, r => //如果委托的方法需要参数，那在最前面加入
                {
                    Console.WriteLine("r.AsyncState: {0}", r.AsyncState); //AsyncState 是传入的参数 "123"！
                    Console.WriteLine("r.IsCompleted: {0}", r.IsCompleted);
                }, "123"); //最后这个是用来玩的？ 不是，r.AsyncState就是它！


                new Thread(() => //在一个线程里等待结果（对比MAIN的位置即可）
                {
                    if (res.AsyncWaitHandle.WaitOne()) //阻塞、等待完成 - 可以设置等待时间！ 又成了顺序执行了
                    {
                        Console.WriteLine("result is {0}", func.EndInvoke(res)); //func.EndInvoke(res) 可以获取返回结果！
                    }
                }).Start();

            }

            Console.WriteLine("MAIN - 我的位置很重要，仔细观察哈");
            Console.ReadKey();
        }

        static int NUM = 77;
        static int IncrAndGet()
        {
            Console.WriteLine("IncrAndGet in");
            Thread.Sleep(3000);
            Console.WriteLine("IncrAndGet out");

            return ++NUM;

        }
        static int AddAndGet(int x)
        {
            Console.WriteLine("AddAndGet in");
            Thread.Sleep(3000);
            Console.WriteLine("AddAndGet out");
            NUM += x;
            return NUM;

        }
        static void Incr()
        {
            Console.WriteLine("Incr in");
            NUM++;
            Thread.Sleep(1000);
            Console.WriteLine("Incr out");
        }
        static void Print()
        {
            Console.WriteLine("Print in");
            Console.WriteLine("the num is {0}!", NUM);

            Console.WriteLine("Print out");
        }
    }
}
